<template>
  <div class="history-chart">
    <div class="chart-header">
      <div class="controls">
        <DatePicker
          type="daterange"
          :value="dateRange"
          style="width: 220px"
          @on-change="handleDateChange"
          placeholder="选择日期范围"
        />
        <Select
          :value="period"
          style="width: 120px"
          @on-change="handlePeriodChange"
        >
          <Option value="day" :disabled="disabledPeriods.day">日</Option>
          <Option value="week" :disabled="disabledPeriods.week">周</Option>
          <Option value="month" :disabled="disabledPeriods.month">月</Option>
          <Option value="quarter" :disabled="disabledPeriods.quarter"
            >季度</Option
          >
          <Option value="year" :disabled="disabledPeriods.year">年</Option>
        </Select>
        <CheckboxGroup
          v-if="showLineSelect"
          :value="selectLine"
          @on-change="handleLineChange"
        >
          <Checkbox label="hang_group" border>挂组数</Checkbox>
          <Checkbox label="work_order" border>派工单数</Checkbox>
          <Checkbox label="part" border>零件数</Checkbox>
        </CheckboxGroup>
        <RadioGroup
          :value="metric"
          v-if="showMetricSelect"
          type="button"
          @on-change="handleMetricChange"
        >
          <Radio label="hang_group">挂组数</Radio>
          <Radio label="work_order">派工单数</Radio>
          <Radio label="part">零件数</Radio>
        </RadioGroup>
      </div>
    </div>
    <div ref="chart" class="chart-container"></div>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Prop, Watch, Emit } from 'vue-property-decorator';
import * as echarts from 'echarts';
import { Select, Option, DatePicker } from 'view-design';
import { T_srv, Tsrv, vue, N_TaskStatistics, TIME_LIMITS } from './config';

@Component({
  components: { Select, Option, DatePicker }
})
export default class HistoryChart extends Vue {
  @Prop({ type: String, required: true }) readonly type!:
    | 'history'
    | 'process_history';

  @Prop({ required: true }) readonly data!: any;

  @Prop({ type: String, default: 'month' }) readonly period!: string;

  @Prop({ type: String, default: 'hang_group' }) readonly metric!: string;

  @Prop({ type: Array, default: () => ['hang_group', 'work_order', 'part'] })
  readonly selectLine!: string[];

  @Prop({
    type: Array,
    default: () => [
      new Date(new Date().getTime() - 3 * 30 * 24 * 60 * 60 * 1000),
      new Date()
    ]
  })
  readonly dateRange!: [Date, Date];

  chart: echarts.ECharts | null = null;

  get title() {
    return this.type === 'history' ? '周期对比任务量' : '按工艺统计任务量';
  }

  get showMetricSelect() {
    return this.type === 'process_history';
  }

  get showLineSelect() {
    return this.type === 'history';
  }

  private get disabledPeriods() {
    const diff =
      new Date(this.dateRange[1]).getTime() -
      new Date(this.dateRange[0]).getTime();
    return {
      day: diff > TIME_LIMITS.DAYS_21,
      week: diff > TIME_LIMITS.MONTHS_3,
      month: diff > TIME_LIMITS.QUARTERS_3,
      quarter: diff > TIME_LIMITS.YEARS_3
    };
  }

  mounted() {
    this.initChart();
    window.addEventListener('resize', this.handleResize);
  }

  beforeDestroy() {
    if (this.chart) {
      window.removeEventListener('resize', this.handleResize);
      this.chart.dispose();
    }
  }

  @Watch('data', { deep: true })
  @Watch('period')
  @Watch('metric')
  @Watch('dateRange', { deep: true })
  @Watch('selectLine', { deep: true })
  onDataChange() {
    this.updateChart(true);
  }

  initChart() {
    this.chart = echarts.init(this.$refs.chart as HTMLElement);
    this.updateChart();
  }

  private handleResize() {
    this.chart?.resize();
  }

  updateChart(forceUpdate = false) {
    if (!this.chart) return;

    const option = {
      title: {
        text: this.title,
        left: 'center'
      },
      tooltip: {
        trigger: 'axis'
      },
      xAxis: {
        type: 'category',
        data: this.getXAxisData(),
        axisLabel: {
          interval: 0,
          rotate: this.period === 'day' ? 45 : 0
        }
      },
      yAxis: {
        type: 'value'
      },
      toolbox: {
        right: 10,
        feature: {
          saveAsImage: {}
        }
      },
      series: this.getSeriesData(),
      color: ['#FFA500', '#FF8C00', '#32CD32'],
      legend: {
        data:
          this.type === 'history'
            ? ['挂组数', '派工单数', '零件数']
            : this.data.reduce((prev, next) => {
                if (prev.indexOf(next.process) === -1) {
                  prev.push(next.process);
                }
                return prev;
              }, []),
        bottom: 0,
        itemWidth: 14,
        itemHeight: 14,
        textStyle: {
          color: '#333'
        }
      }
    };

    this.chart.setOption(option, {
      notMerge: forceUpdate
    });
  }

  getXAxisData() {
    if (this.type === 'history') {
      return this.data.map((d: any) => d.date);
    }
    return this.data.reduce((prev, next) => {
      if (prev.indexOf(next.date) === -1) {
        prev.push(next.date);
      }
      return prev;
    }, []);
  }

  getSeriesData() {
    if (this.type !== 'history') {
      return this.data.reduce((prev, next) => {
        if (prev.find(a => a.name === next.process) === undefined) {
          prev.push({
            name: next.process,
            type: 'line',
            data: this.data
              .filter(a => a.process === next.process)
              .map(a => a.num)
          });
        }
        return prev;
      }, []);
    }

    const seriesMap = {
      hang_group: {
        name: '挂组数',
        type: 'line',
        data: this.data.map(d => d.hang_group)
      },
      work_order: {
        name: '派工单数',
        type: 'line',
        data: this.data.map(d => d.work_order)
      },
      part: {
        name: '零件数',
        type: 'line',
        data: this.data.map(d => d.part)
      }
    };

    return this.selectLine.map(line => seriesMap[line]);
  }

  @Emit('update:dateRange')
  handleDateChange(dates: [Date, Date]) {
    this.$emit('date-change', { dates, type: this.type });
  }

  @Emit('update:period')
  handlePeriodChange(period: string) {
    this.$emit('period-change', period, this.type);
  }

  @Emit('update:metric')
  handleMetricChange(metric: string) {
    this.$emit('metric-change', metric);
  }

  @Emit('update:selectLine')
  handleLineChange(lines: string[]) {
    this.$emit('line-change', lines);
  }
}
</script>

<style lang="scss" scoped>
.history-chart {
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #fff;
  border-radius: 5px;
  padding: 10px 0 0 10px;

  .chart-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;

    .controls {
      display: flex;
      gap: 8px;
    }
  }

  .chart-container {
    flex: 1;
    min-height: 0;
    padding: 0 20px 20px 20px;

    ::v-deep .echarts {
      width: 100%;
      height: 100%;
    }
  }
}
</style>
